<?php

/*-------------------------------------------------------------------------------------------------------------------------------------- */
// oop
class Fruit{
    protected $name;
    protected const value = 10;
    protected $color = "红色";

    // 构造函数
    public function __construct($name){
        echo "__construct()" . "<br>";
        $this->setName($name);
    }

    public function getName(){
        echo $this->name;
    }
    private function setName($name){
        $this->name = $name;
    }

    public function getValue(){
        // echo $this->value;
        echo self::value;
    }
    private function setValue($value){
        // $this->value = $value;
        // self::value = $value; // const 常量不能被赋值了
    }

    public function getColor(){
        echo $this->color;
    }
    protected function setColor($color){
        $this->color = $color;
    }

    // 析构函数
    public function __destruct(){
        echo "__destruct()" . "<br>";
    }
};

// $apple = new Fruit("apple");
// // $apple->setName("apple");
// $apple->getName();



/*-------------------------------------------------------------------------------------------------------------------------------------- */
// 继承和多态是为了代码的复用
class Apple extends Fruit{
    // const name = "apple";
    private $value;

    public function message(){
        echo "<br>" . $this->name . " 的颜色：" . $this->color . ", 价格：" . $this->value . "<br>"; 
    }

    public function SetColor($color){
        // $this->setColor($color); // error

        parent::setColor($color); // 调用父类的成员得使用 parent，调用父类的成员变量可以使用 $this
        
        // $this->color = $color; // 因为父类的 $color 成员是一个 protected 类型的变量，所以子类是可以用的
    }

    // 构造函数
    public function __construct($name){
        parent::__construct($name);

        echo "Apple: __construct()";
    }
    // 析构函数
    public function __destruct(){
        echo "Apple: __destruct()";
    }
};

// $apple = new Apple("apple");
// $apple->message();

// $apple->SetColor("黑色");
// $apple->message();



/*-------------------------------------------------------------------------------------------------------------------------------------- */
// static 成员变量(全局的生命周期，独一份的)， static 成员函数(只能使用 static 成员变量)
// static 和 const 的调用形式差不多的哦，都是用的 self，注意 static 有 $，const 没有 $
class Book{
    static $pageNumber = 0;
    private $number = 0;

    public function __construct(){
        // pageNumber 是会自增的哦
        echo "<br>当前 pageNumber 是：" . ++self::$pageNumber;
        echo "<br>当前 number 是：" . ++$this->number . "<br>";
    }

    public static function getPageNumber(){
        echo "pageNumber: " . self::$pageNumber . "<br>";
        // echo "number: " . $this->number . "<br>"; // error
    }
};

// $book = new Book();
// $book->getPageNumber();



/*-------------------------------------------------------------------------------------------------------------------------------------- */
// final: 被 final 修饰的类和方法就是 "最终的版本"，被定义的类不可以被继承，不可以被覆盖。

final class superMan{
    function __construct(){
        echo "superMan" . "<br>";
    }
};

// class MaxSuperMan extends superMan{};

// new MaxSuperMan(); // Fatal error: Class MaxSuperMan may not inherit from final class (superMan) in D:\wamp\www\part16-php_oop\demo_oop.php on line 122



/*-------------------------------------------------------------------------------------------------------------------------------------- */

// abstract 抽象类：不能被实例化的类，只能做为其它类的父类来使用

abstract class xxx{};

// new xxx(); //Error: Cannot instantiate abstract class xxx in D:\wamp\www\part16-php_oop\demo_oop.php on line 134



/*-------------------------------------------------------------------------------------------------------------------------------------- */

// 接口：implements 相比较 abstract 可以同时继承多个类

// 接口定义
interface Animal{
    public function makeSound();
}
interface Robot{
    public function makeAction();
}

// 类定义
class Cat implements Animal{
    public function makeSound(){
        echo "喵";
    }
}

class Mouse implements Animal{
    public function makeSound(){
        echo "吱";
    }
}

class Dog implements Animal, Robot{
    public function makeSound(){
        echo "汪";
    }
    public function makeAction(){
        echo "机器人";
    }
}

// 实例化
$cat = new Cat();
$dog = new Dog();
$mouse = new Mouse();

